<?php

namespace app\shop\controller;

use think\facade\Db;
use AopSDK\request\AlipayOpenAgentCreateRequest;
use AopSDK\request\AlipayOpenAgentFacetofaceSignRequest;
use AopSDK\request\AlipayOpenAgentConfirmRequest;
use AopSDK\request\AlipayOpenAgentOrderQueryRequest;

//use AopSDK\request\AlipayOpenAgentSignstatusQueryRequest;

class JinjianAlipay extends Base
{
    public function getInitData()
    {
        $shop_id = self::$shop['id'];
        $agent_id = Db::name('shop')
            ->where('id', $shop_id)
            ->value('agent_id');
        $agent = Db::name('agent')
            ->where('id', $agent_id)
            ->find();

        $serverArr = Db::name('server')
            ->where('type', 'alipay')
            ->field('id,title as text,config')
            ->select()->each(function ($item) {
                $config = @json_decode($item['config'], true);
                $item['pid'] = isset($config['pid']) ? $config['pid'] : '';
                unset($item['config']);
                return $item;
            });
        $tradeArr = Db::name('jinjian_alipay_trade')
            ->where('pid', 0)
            ->field('id,trade as text,mcc_code,desc')
            ->select()->each(function ($item) {
                $item['children'] = Db::name('jinjian_alipay_trade')
                    ->where('pid', $item['id'])
                    ->field('trade as text,mcc_code,desc')
                    ->select()
                    ->toArray();
                unset($item['id']);
                return $item;
            });

        $rate_min = min(60, max(intval($agent['rate_shop']), 38));
        return successJson([
            'serverArr' => $serverArr,
            'tradeArr' => $tradeArr,
            'rateMin' => $rate_min,
            'rateMax' => 60
        ]);
    }

    /**
     * 获取服务商配置参数
     */
    private static function getServerConfig($server_id)
    {
        $server = Db::name('server')
            ->where('id', $server_id)
            ->value('config');
        $server = @json_decode($server, true);
        return $server;
    }

    /**
     * @return string
     * 上传图片
     */
    public function uploadImage()
    {
        $content = input('content', '', 'trim');
        $path = $this->saveBase64Image($content);
        if (!$path) {
            return errorJson('上传失败，请重试！');
        }
        // 压缩图片
        $filepath = '.' . $path;
        \think\Image::open($filepath)->thumb(1200, 1200)->save($filepath);

        return successJson([
            'path' => mediaUrl($path)
        ]);
    }

    /**
     * @return string
     * 上传营业执照
     */
    public function uploadYYzz()
    {
        $content = input('content', '', 'trim');
        $path = $this->saveBase64Image($content);
        if (!$path) {
            return errorJson('上传失败，请重试！');
        }
        // 压缩图片
        $filepath = '.' . $path;
        \think\Image::open($filepath)->thumb(1500, 1500)->save($filepath);
        // OCR识别
        $content = base64_encode(file_get_contents($filepath));
        $ocrResult = $this->yyzzOcr($content);
        $return = [
            'path' => mediaUrl($path)
        ];
        $return = array_merge($return, $ocrResult);

        return successJson($return);
    }

    /**
     * @param $content
     * @return string
     */
    private function saveBase64Image($content)
    {
        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $content, $result)) {
            $type = $result[2];
            $dir = './upload/image/';
            if (!file_exists($dir)) {
                mkdir($dir, 0755, true);
            }
            if ($type == 'jpeg') {
                $type = 'jpg';
            }
            $path = $dir . uniqid() . '.' . $type;
            if (file_put_contents($path, base64_decode(str_replace($result[1], '', $content)))) {
                return str_replace('./', '/', $path);
            } else {
                return '';
            }
        } else {
            return '';
        }
    }

    /**
     * 营业执照ocr
     */
    private function yyzzocr($content)
    {
        $result = [
            'name' => '',
            'number' => '',
            'address_code' => '',
            'province' => '',
            'city' => '',
            'region' => '',
            'address' => '',
            'legal_person' => '',
            'time_start' => '',
            'time_end' => '',
        ];
        $image = urlencode($content);
        $image_type = '0';
        if ($image) {
            $setting = getSystemSetting('jinjian');
            if (!empty($setting['yyzz_appcode'])) {
                $appCode = $setting['yyzz_appcode'];
            } else {
                return $result;
            }
            $apiUrl = 'https://businessid.market.alicloudapi.com/ai_business_license/v1';
            $headers = [
                "Authorization:APPCODE " . $appCode,
                "Content-Type:application/x-www-form-urlencoded; charset=UTF-8"
            ];
            $bodys = "IMAGE=" . $image . "&IMAGE_TYPE=" . $image_type;
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
            curl_setopt($curl, CURLOPT_URL, $apiUrl);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($curl, CURLOPT_FAILONERROR, false);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $bodys);
            $res = curl_exec($curl);


            $res = json_decode($res, true);

            $res = $res['营业执照识别实体信息'];
            $result = [
                'name' => $res['企业名称'],
                'number' => $res['企业统一社会信用编码'],
                'address_code' => $res['企业所在地国家行政编码'],
                'province' => $res['企业所在省份'],
                'city' => $res['企业所在城市'],
                'region' => $res['企业所在区域'],
                'address' => $res['企业注册地址'],
                'legal_person' => $res['企业法人'],
                'time_start' => $res['企业注册时间'],
                'time_end' => $res['企业营业期限结束时间'] == '无' ? '' : $res['企业营业期限结束时间']
            ];
        }

        return $result;
    }

    public function doSubmit()
    {
        $shop_id = self::$shop['id'];
        $server_id = input('server_id', 0, 'intval');
        $server_pid = input('server_pid', '', 'trim');
        $server_name = input('server_name', '', 'trim');
        $account = input('account', '', 'trim');
        $activities_rate = input('activities_rate', '', 'trim');
        $biz_store_name = input('biz_store_name', '', 'trim');
        $indoor_pic = input('indoor_pic', '', 'trim');
        $license_copy = input('license_copy', '', 'trim');
        $license_number = input('license_number', '', 'trim');
        // $long_term = input('long_term', '', 'trim');
        $mcc_code = input('mcc_code', '', 'trim');
        $contact_mobile = input('contact_mobile', '', 'trim');
        $contact_name = input('contact_name', '', 'trim');
        $qualifications = input('qualifications', '', 'trim');
        $qualifications_desc = input('qualifications_desc', '', 'trim');
        $store_entrance_pic = input('store_entrance_pic', '', 'trim');
        $trade_title = input('trade_title', '', 'trim');
        $valid_time_end = input('valid_time_end', '', 'trim');


        $shop = Db::name('shop')
            ->where('id', $shop_id)
            ->find();

        // 保存数据
        $data = [];
        // 基础信息

        $data['shop_id'] = $shop_id;
        $data['server_id'] = $server_id;
        $data['agent_id'] = $shop['agent_id'];
        $data['server_pid'] = $server_pid;
        $data['account'] = $account;
        $data['activities_rate'] = $activities_rate;
        $data['qualifications'] = $qualifications;
        $data['mcc_code'] = $mcc_code;
        // 经营资料
        $data['biz_store_name'] = $biz_store_name;
        $data['store_entrance_pic'] = $store_entrance_pic;
        $data['indoor_pic'] = $indoor_pic;
        // 主体资料
        $data['license_copy'] = $license_copy;
        $data['license_number'] = $license_number;
        // $data['long_term'] = $long_term;
        $data['valid_time_end'] = $valid_time_end;
        $data['contact_mobile'] = $contact_mobile;
        $data['contact_name'] = $contact_name;
        $data['ext'] = json_encode([
            'server_name' => $server_name,
            'trade_title' => $trade_title,
            'qualifications_desc' => $qualifications_desc
        ]);
        $data['update_time'] = time();

        $info = Db::name('jinjian_alipay')
            ->where('shop_id', $shop_id)
            ->find();

        if ($info) {
            Db::name('jinjian_alipay')
                ->where('shop_id', $shop_id)
                ->update($data);
        } else {
            $data['add_time'] = time();
            Db::name('jinjian_alipay')
                ->insert($data);
        }


        // ------------
        $serverConfig = self::getServerConfig($server_id);
        $aop = get_alipay_aop($serverConfig);
        // 1、开启代签约事务
        $data['batch_no'] = self::agentCreate($aop, $data);
        // 2、提交代签约
        self::agentFacetoface($aop, $data);

        // 3、提交事务
        self::agentConfirm($aop, $data);

        return successJson('', '提交成功，请等待支付宝审核');
    }

    /**
     * 1、支付宝开启代商户签约事务
     */
    public static function agentCreate($aop, $data)
    {
        $request = new AlipayOpenAgentCreateRequest ();
        $request->setBizContent(json_encode([
            'account' => $data['account'],
            'contact_info' => [
                'contact_name' => $data['contact_name'],
                'contact_mobile' => $data['contact_mobile']
            ]
        ]));
        $result = $aop->execute($request);
        $responseNode = str_replace('.', '_', $request->getApiMethodName()) . '_response';
        $resultCode = $result->$responseNode->code;
        if (!empty($resultCode) && $resultCode == 10000) {
            $batch_no = $result->$responseNode->batch_no;
            $batch_status = $result->$responseNode->batch_status;

            Db::name('jinjian_alipay')
                ->where('shop_id', $data['shop_id'])
                ->update([
                    'batch_no' => $batch_no,
                    'batch_status' => $batch_status
                ]);

            return $batch_no;
        } else {
            return errorJson($result->$responseNode->sub_msg);
        }
    }

    /**
     * 2、代签约当面付产品
     */
    private static function agentFacetoface($aop, $data)
    {
        $request = new AlipayOpenAgentFacetofaceSignRequest();
        $request->setBatchNo($data['batch_no']);
        $request->setMccCode($data['mcc_code']);
        $request->setShopName($data['biz_store_name']);
        $request->setBusinessLicenseNo($data['license_number']);
        // $request->setSpecialLicensePic('@'.'本地文件路径');
        $request->setBusinessLicensePic('@' . realpath('.' . $data['license_copy']));
        $request->setBusinessLicenseMobile($data['contact_mobile']);

        $request->setRate($data['activities_rate']);
        $request->setSignAndAuth(true);
        if ($data['valid_time_end'] == '长期') {
            $request->setLongTerm(true);
        } else {
            $request->setLongTerm(false);
            $request->setDateLimitation($data['valid_time_end']);
        }
        $request->setShopScenePic('@' . realpath('.' . $data['indoor_pic']));
        $request->setShopSignBoardPic('@' . realpath('.' . $data['store_entrance_pic']));
        if (!empty($data['qualifications'])) {
            $request->setSpecialLicensePic('@' . realpath('.' . $data['qualifications']));
        }
        $result = $aop->execute($request);

        $responseNode = str_replace('.', '_', $request->getApiMethodName()) . '_response';
        $resultCode = $result->$responseNode->code;

        if (empty($resultCode) || $resultCode == 10000) {
            return true;
        } else {
            if(strpos($result->$responseNode->sub_msg, '已签约此产品') !== false) {
                $serverConfig = self::getServerConfig($data['server_id']);
                $redirect_uri = getAlipayAuthUrl();

                Db::name('jinjian_alipay')
                    ->where('shop_id', $data['shop_id'])
                    ->update([
                        'batch_status' => 'submit',
                        'order_status' => 'MERCHANT_NEED_AUTH',
                        'auth_url' => 'https://openauth.alipay.com/oauth2/appToAppBatchAuth.htm?app_id=' . $serverConfig['appid'] . '&application_type=WEBAPP&redirect_uri=' . urlencode($redirect_uri) . '&state=' . $data['shop_id'],
                        'update_time' => time()
                    ]);

                return successJson('', $result->$responseNode->sub_msg);
            } else {
                return errorJson($result->$responseNode->sub_msg);
            }
        }
    }

    /**
     * 3、提交代商户签约事务
     */
    private static function agentConfirm($aop, $data)
    {
        $request = new AlipayOpenAgentConfirmRequest ();
        $request->setBizContent(json_encode([
            'batch_no' => $data['batch_no']
        ]));
        $result = $aop->execute($request);
        $responseNode = str_replace('.', '_', $request->getApiMethodName()) . '_response';
        $resultCode = $result->$responseNode->code;
        if (!empty($resultCode) && $resultCode == 10000) {
            $now = time();
            $saveData = [
                'batch_status' => 'submit',
                'order_status' => 'MERCHANT_AUDITING'
            ];
            if(isset($result->$responseNode->user_id)) {
                $saveData['merchant_pid'] = $result->$responseNode->user_id;
            }
            if(isset($result->$responseNode->app_auth_token)) {
                $saveData['app_auth_token'] = $result->$responseNode->app_auth_token;
            }
            if(isset($result->$responseNode->app_refresh_token)) {
                $saveData['app_refresh_token'] = $result->$responseNode->app_refresh_token;
            }
            if(isset($result->$responseNode->expires_in)) {
                $saveData['expires_in'] = $now + intval($result->$responseNode->expires_in);
            }
            if(isset($result->$responseNode->re_expires_in)) {
                $saveData['re_expires_in'] = $now + intval($result->$responseNode->re_expires_in);
            }
            Db::name('jinjian_alipay')
                ->where('shop_id', $data['shop_id'])
                ->update($saveData);
        } else {
            return errorJson($result->$responseNode->sub_msg);
        }
    }

    /**
     * 查询上次提交的表单内容
     */
    public function getLastForm()
    {
        $shop_id = self::$shop['id'];
        $shop = Db::name('shop')
            ->where([
                'id' => $shop_id
            ])
            ->find();
        if (!$shop) {
            return errorJson('商户不存在，请刷新页面重试');
        }
        $info = Db::name('jinjian_alipay')
            ->where([
                'shop_id' => $shop_id
            ])
            ->find();
        if (!$info) {
            // 取微信提交的数据
            $wxInfo = Db::name('jinjian_wxpay')
                ->where([
                    'shop_id' => $shop_id
                ])
                ->find();
            if (!$wxInfo) {
                return successJson([
                    'form' => null,
                    'ext' => null
                ]);
            }
            $info = [
                'activities_rate' => $wxInfo['activities_rate'],
                'license_copy' => $wxInfo['license_copy'],
                'license_number' => $wxInfo['license_number'],
                //'valid_time_end' => $wxInfo['valid_time_end'],
                'contact_name' => $wxInfo['legal_person'],
                'contact_mobile' => $wxInfo['mobile_phone'],
                'biz_store_name' => $wxInfo['biz_store_name'],
                'store_entrance_pic' => $wxInfo['store_entrance_pic'],
                'indoor_pic' => $wxInfo['indoor_pic']
            ];
            if ($wxInfo['qualifications']) {
                $qualifications = explode(',', $wxInfo['qualifications']);
                $info['qualifications'] = $qualifications[0];
            }
            $ext = null;
        } else {
            unset($info['id'], $info['agent_id'], $info['batch_no'], $info['merchant_pid'], $info['order_status'], $info['confirm_url'], $info['reject_reason'], $info['update_time'], $info['add_time']);
            $ext = $info['ext'] ? json_decode($info['ext'], true) : null;
            unset($info['ext']);
        }

        return successJson([
            'form' => $info,
            'ext' => $ext
        ]);
    }

    /**
     * 查询申请单状态
     */
    public function getApplyResult()
    {
        $refresh = input('refresh', 0, 'intval');
        $shop_id = self::$shop['id'];
        $shop = Db::name('shop')
            ->where([
                'id' => $shop_id
            ])
            ->find();
        if (!$shop) {
            return errorJson('商户不存在，请刷新页面重试');
        }

        if ($refresh) {
            $this->flushApplyStatus($shop_id);
        }

        $info = Db::name('jinjian_alipay')
            ->where('shop_id', $shop_id)
            ->field('server_id,batch_no,batch_status,activities_rate,order_status,merchant_pid,app_auth_token,expires_in,confirm_url,auth_url,reject_reason,update_time,add_time')
            ->find();
        if (!$info) {
            return errorJson('没有找到进件记录');
        }
        $info['add_time'] = date('Y-m-d H:i:s', $info['add_time']);
        $info['update_time'] = date('Y-m-d H:i:s', $info['update_time']);

        // 自动配置到商户支付参数
        if (!empty($info['merchant_pid']) && !empty($info['app_auth_token'])) {
            Db::name('shop')
                ->where('id', $shop_id)
                ->update([
                    'alipay_config' => json_encode([
                        'alipay_status'=> 1,
                        'alipay_type' => 'server',
                        'alipay_server_id' => $info['server_id'],
                        'alipay_pid' => $info['merchant_pid'],
                        'alipay_token' => $info['app_auth_token'],
                        'alipay_rate' => $info['activities_rate']
                    ])
                ]);
        }

        return successJson($info);

    }

    /**
     * 刷新申请单状态
     */
    private function flushApplyStatus($shop_id)
    {
        $info = Db::name('jinjian_alipay')
            ->where('shop_id', $shop_id)
            ->find();
        if (!$info || empty($info['batch_no'])) {
            return errorJson('刷新失败，没有找到进件记录');
        }
        if ($info['order_status'] == 'MERCHANT_NEED_AUTH' || $info['order_status'] == 'MERCHANT_CONFIRM_SUCCESS') {
            return true;
        }

        $request = new AlipayOpenAgentOrderQueryRequest();
        $request->setBizContent(json_encode([
            'batch_no' => $info['batch_no']
        ]));
        $serverConfig = self::getServerConfig($info['server_id']);
        $aop = get_alipay_aop($serverConfig);
        $result = $aop->execute($request);
        $responseNode = str_replace('.', '_', $request->getApiMethodName()) . '_response';
        $resultCode = $result->$responseNode->code;
        if (!empty($resultCode) && $resultCode == 10000) {
            Db::name('jinjian_alipay')
                ->where('shop_id', $shop_id)
                ->update([
                    'order_status' => $result->$responseNode->order_status,
                    'confirm_url' => isset($result->$responseNode->confirm_url) ? $result->$responseNode->confirm_url : '',
                    'reject_reason' => isset($result->$responseNode->reject_reason) ? $result->$responseNode->reject_reason : '',
                    'merchant_pid' => $result->$responseNode->merchant_pid,
                    'update_time' => time()
                ]);
        } else {
            Db::name('jinjian_alipay')
                ->where('shop_id', $shop_id)
                ->update([
                    'batch_status' => 'init',
                    'update_time' => time()
                ]);
            //return errorJson($result->$responseNode->sub_msg);
        }
    }

    /**
     * 查询商户当面付签约状态
     */
    /*private function agentSignStatus($account)
    {
        $request = new AlipayOpenAgentSignstatusQueryRequest();
        $request->setBizContent(json_encode([
            'pid' => $account,
            'product_codes' => [
                'I1011000100000000001' // 当面付产品码
            ]
        ]));
        $aop = get_alipay_aop(self::$serverConfig);
        $result = $aop->execute($request, '202111BB60b1b8be941e4a7db7c3c9ed3508fD64');
        $responseNode = str_replace('.', '_', $request->getApiMethodName()) . '_response';
        $resultCode = $result->$responseNode->code;
        if (!empty($resultCode) && $resultCode == 10000) {
            $signStatusList = $result->$responseNode->sign_status_list;
            $status = $signStatusList[0]->status;
            if (empty($status)) {
                return [
                    'errno' => 1,
                    'message' => '查询签约状态失败'
                ];
            }
            $msgArr = [
                'none' => '未签约',
                'valid' => '当面付已签约并生效',
                'restrictValid' => '受限生效（资料不全，功能受限）',
                'audit' => '签约正在审核中',
                'waitConfirm' => '签约审核通过，需商户确认后生效',
                'auditReject' => '签约审核未通过',
                'invalid' => '合约失效，请重新签约',
                'restrictInvalid' => '合约失效（且资料不全），请重新签约'
            ];
            return [
                'errno' => 0,
                'status' => $status,
                'message' => isset($msgArr[$status]) ? $msgArr[$status] : ''
            ];
        } else {
            return [
                'errno' => 1,
                'message' => $result->$responseNode->sub_msg
            ];
        }
    }*/

    /**
     * 换取刷新令牌
     **/
    /*public function alipay_authtoken($data = [])
    {
        vendor('AopSDK.AopClient');
        vendor('AopSDK.SignData');
        $aop = new \AopClient ();
        $merchant = M('user_jinjian')->where(['userid' => $data['merchant_id']])->find();
        $admin_config = D('admin_config')->where(['adminid' => $merchant['adminid']])->find();
        $content = json_decode($admin_config['content'], true);
        $systemconfig = $content['ALIPAY_CONFIG'];

        $aop = new \AopClient();
        $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
        $aop->appId = $systemconfig['app_id'];
        $aop->rsaPrivateKey = $systemconfig['merchant_private_key'];
        $aop->alipayrsaPublicKey = $systemconfig['alipay_public_key'];
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->format = 'json';

        vendor('AopSDK.request.AlipayOpenAuthTokenAppRequest');
        $request = new \AlipayOpenAuthTokenAppRequest();
        $array = array(
            'grant_type' => 'authorization_code',
            'code' => $data['app_auth_code']
        );
        $request->setBizContent(json_encode($array));
        $result = $aop->execute($request);
        $responseNode = str_replace('.', '_', $request->getApiMethodName()) . '_response';
        $resultCode = $result->$responseNode->code;
        if (!empty($resultCode) && $resultCode == 10000) {
            $t = $result->$responseNode->tokens[0];
            $da['merchant_pid'] = $t->user_id;
            $da['app_auth_token'] = $t->app_auth_token;
            $da['app_refresh_token'] = $t->app_refresh_token;
            $rt = M('retail_merchant_jinjian')->where(['merchantid' => $data['merchant_id']])->save($da);
            if ($rt) {
                $this->alipay_create($data);
            }
        } else {
            $this->alipay_error($result->$responseNode->sub_msg);
        }
    }*/

    public function alipay_success($msg)
    {
        die($msg);
    }

    public function alipay_error($msg)
    {
        die($msg);
    }
}
